python generator
関数の中にyieldがあれば、それはジェネレータ関数
ジェネレータは、iterableでないといけない。
iteraterと比較した際の利点は....
iteratorだと interateする全体を一旦メモリで持つ必要があるが、generatorなら"iterateされてきたもの"のみが参照されるので、メモリ量少ない。
無限iteratorでも問題ない。iterateするなかで、打ち切りロジック?を入れれば良い。
code: foo.py
def sample_gen():
x = None
while True:
x.something()
x = yield y()
こんな感じだと、gen=sample_gen(); したgenを
next(gen)するたびに、yieldの行まで実行が進む。呼び出し側(next()する方)には y()が返される(yが生成される)
gen.send(foo)するたびに、これもyieldの行まで実行が進むが、
xにfooの値が代入されて進むのがnext()と違う点。
あとは、関数実行か、メソッド実行かも、next()との差異
値を入れて、(状況を保持してる)generator関数から生成した値を返してもらうイメージが取りやすい?
generator の中で、もう一つ下の階層?とやりとり(next, send)したいときは、yield from を使う。
シミュレーションで、複数の実体があり、個別の実体でgenerator的な動きをする際に、yield fromは有用。
ここに例をストックしておいて、自分の手札にしておきたい。
ここを読んでて、alist[0]みたいなことでなく、next(x for x in alist if re.search(x, "a_str") )で最初の値を取るみたいにしてた。こちらのが、速そう。仮にリストが大きいならメリットあるかも。
generator関連のkeyword
send()
`Generator.send("value") で、 generatorの利用側から、定義側のval = yield x の部分のvalに"value"を渡せる。
使いどころは,,,,
coroutineを、お客とキッチンでする。インターフェスは、dumb waiter.
参考